# coding = utf-8
# !/usr/bin/python
# 新时代青年 2025.06.25 getApp第三版
import re
import sys
import uuid
import json
import base64

import requests
from Crypto.Cipher import AES
from base.spider import Spider
from Crypto.Util.Padding import pad
from Crypto.Util.Padding import unpad
sys.path.append('..')

headerx = {
    'User-Agent': 'okhttp/3.10.0' # okhttp/3.14.9
          }

class Spider(Spider):
    global headerx
    init_data = ''
    search_verify = ''

    def getName(self):
        return "首页"

    def init(self, extend):
        js1=json.loads(extend)
        host = js1['host']
        if re.match(r'^https:\/\/.*\.txt$',host):
            host = self.fetch(host, headers=headerx, timeout=10).text.rstrip('/')
        self.xurl = host + js1['api']
        self.key = js1['datakey']
        self.iv = js1['dataiv']

        res = self.fetch(self.xurl + '.index/initV119', headers=headerx).json()
        encrypted_data = res['data']
        response = self.decrypt(encrypted_data)
        init_data = json.loads(response)
        self.init_data = init_data
        self.search_verify = init_data['config'].get('system_search_verify_status',False)

    def homeContent(self, filter):
        kjson = self.init_data
        classes = []
        for i in kjson['type_list']:
            if i['type_name'] in ['全部', 'QQ'] or '企鹅群' in i['type_name']:
                continue
            classes.append({
                "type_id": i['type_id'],
                "type_name": i['type_name']
            })

        return {"class": classes}

    def homeVideoContent(self):
        videos = []
        kjson = self.init_data
        for i in kjson['type_list']:
            for item in i['recommend_list']:
                vod_id = item['vod_id']
                name = item['vod_name']
                pic = item['vod_pic']
                remarks = item['vod_remarks']
                video = {
                    "vod_id": vod_id,
                    "vod_name": name,
                    "vod_pic": pic,
                    "vod_remarks": remarks
                }
                videos.append(video)
        return {'list': videos}

    def categoryContent(self, cid, pg, filter, ext):
        videos = []
        payload = {
            'area': "全部",
            'year': "全部",
            'type_id': cid,
            'page': str(pg),
            'sort': "最新",
            'lang': "全部",
            'class': "全部"
        }
        url = f'{self.xurl}.index/typeFilterVodList'
        res = self.post(url=url, headers=headerx,data=payload).json()
        encrypted_data = res['data']
        kjson = self.decrypt(encrypted_data)
        kjson1 = json.loads(kjson)
        for i in kjson1['recommend_list']:
            id = i['vod_id']
            name = i['vod_name']
            pic = i['vod_pic']
            remarks = i['vod_remarks']
            video = {
                "vod_id": id,
                "vod_name": name,
                "vod_pic": pic,
                "vod_remarks": remarks
            }
            videos.append(video)
        result = {'list': videos, 'page': pg, 'pagecount': 9999, 'limit': 90, 'total': 999999}
        return result

    def detailContent(self, ids):
        did = ids[0]
        payload = {
            'vod_id': did,
        }
        api_endpoints = ['vodDetail', 'vodDetail2']

        for endpoint in api_endpoints:
            url = f'{self.xurl}.index/{endpoint}'
            response = self.post(url=url, headers=headerx, data=payload)

            if response.status_code == 200:
                response_data = response.json()
                encrypted_data = response_data['data']
                kjson1 = self.decrypt(encrypted_data)
                kjson = json.loads(kjson1)
                break
        videos = []
        play_form = ''
        play_url = ''

        actor = kjson['vod']['vod_actor']
        director = kjson['vod'].get('vod_director', '')
        area = kjson['vod']['vod_area']
        name = kjson['vod']['vod_name']
        year = kjson['vod']['vod_year']
        content = kjson['vod']['vod_content']
        subtitle = kjson['vod']['vod_remarks']
        desc = kjson['vod']['vod_lang']
        remark = '时间:' + subtitle + ' 语言:' + desc
        for line in kjson['vod_play_list']:
            keywords = ['防走丢', '群', '防失群', 'Q']
            if any(keyword in line['player_info']['show'] for keyword in keywords):
                continue
            play_form += line['player_info']['show'] + '$$$'
            parse = line['player_info']['parse']
            player_parse_type = line['player_info']['player_parse_type']
            kurls = ""
            for vod in line['urls']:
                kurl = vod['url']
                if '.m3u8' in kurl:
                    kurls += str(vod['name']) + '$' + vod['url'] + '#'
                else:
                    if 'm3u8' not in kurl:
                        token = 'token+' + vod['token']
                        kurls += str(vod['name']) + '$' + parse + ',' + vod[
                            'url'] + ',' + token + ',' + player_parse_type + '#'
            kurls = kurls.rstrip('#')
            play_url += kurls + '$$$'
        play_form = play_form.rstrip('$$$')
        play_url = play_url.rstrip('$$$')
        videos.append({
            "vod_id": did,
            "vod_name": name,
            "vod_actor": actor.replace('演员', ''),
            "vod_director": director.replace('导演', ''),
            "vod_content": content,
            "vod_remarks": remark,
            "vod_year": year + '年',
            "vod_area": area,
            "vod_play_from": play_form,
            "vod_play_url": play_url
        })

        return {'list': videos}

    def playerContent(self, flag, id, vipFlags):
        url = ''
        if 'm3u8' in id:
            url = id
        if 'url=' in id:
            aid = id.split(',')
            uid = aid[0]
            kurl = aid[1]
            kjson = uid + kurl
            url2 = f"{kjson}"
            response = self.fetch(url=url2)
            if response.status_code == 200:
                kjson1 = response.json()
                url = kjson1['url']
        else:
            aid = id.split(',')
            bid = aid[-1]
            uid = aid[0]
            kurl = aid[1]
            token = aid[2].replace('token+', '')
            id1 = self.decrypt_wb(kurl)
            payload = {
                'parse_api': uid,
                'url': id1,
                'player_parse_type': bid,
                'token': token
            }
            url1 = f"{self.xurl}.index/vodParse"
            response = self.post(url=url1, headers=headerx, data=payload)
            if response.status_code == 200:
                response_data = response.json()
                encrypted_data = response_data['data']
                kjson = self.decrypt(encrypted_data)
                kjson1 = json.loads(kjson)
                kjson2 = kjson1['json']
                kjson3 = json.loads(kjson2)
                url = kjson3['url']
        result = {"parse": 0, "playUrl": '', "url": url, "header": headerx}
        return result

    def searchContent(self, key, quick, pg="1"):
        videos = []
        payload = {
            'keywords': key,
            'type_id': "0",
            'page': str(pg)
        }
        if self.search_verify:
            verifi = self.Verification()
            print(verifi)
            if verifi is None:
                print('识别验证码失败')
                return {'list':[]}
            payload['code'] = verifi['code']
            payload['key'] = verifi['uuid']

        url = f'{self.xurl}.index/searchList'
        res = self.post(url=url, data=payload, headers=headerx).json()
        if not res.get('data'):
            return {'list':[] ,'msg': res.get('msg')}
        encrypted_data = res['data']
        kjson = self.decrypt(encrypted_data)
        kjson1 = json.loads(kjson)
        for i in kjson1['search_list']:
            id = i['vod_id']
            name = i['vod_name']
            pic = i['vod_pic']
            remarks = i['vod_year'] + ' ' + i['vod_class']

            video = {
                "vod_id": id,
                "vod_name": name,
                "vod_pic": pic,
                "vod_remarks": remarks
            }
            videos.append(video)
        result = {'list': videos, 'page': pg, 'pagecount': 9999, 'limit': 90, 'total': 999999}
        return result

    def localProxy(self, params):
        if params['type'] == "m3u8":
            return self.proxyM3u8(params)
        elif params['type'] == "media":
            return self.proxyMedia(params)
        elif params['type'] == "ts":
            return self.proxyTs(params)
        return None

    def isVideoFormat(self, url):
        pass

    def manualVideoCheck(self):
        pass

    def decrypt(self, encrypted_data_b64):
        key_text = self.key
        iv_text = self.iv
        key_bytes = key_text.encode('utf-8')
        iv_bytes = iv_text.encode('utf-8')
        encrypted_data = base64.b64decode(encrypted_data_b64)
        cipher = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
        decrypted_padded = cipher.decrypt(encrypted_data)
        decrypted = unpad(decrypted_padded, AES.block_size)
        return decrypted.decode('utf-8')

    def decrypt_wb(self, sencrypted_data):
        key_text = self.key
        iv_text = self.iv
        key_bytes = key_text.encode('utf-8')
        iv_bytes = iv_text.encode('utf-8')
        data_bytes = sencrypted_data.encode('utf-8')
        padded_data = pad(data_bytes, AES.block_size)
        cipher = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
        encrypted_bytes = cipher.encrypt(padded_data)
        encrypted_data_b64 = base64.b64encode(encrypted_bytes).decode('utf-8')
        return encrypted_data_b64

    def ocr(self,base64Img):
        dat2 = requests.post("https://api.nn.ci/ocr/b64/text",base64Img,headers=headerx).text
        if dat2:
            return dat2
        else:
            return None

    def Verification(self):
        random_uuid = str(uuid.uuid4())
        dat = self.fetch(f'{self.xurl}.verify/create?key={random_uuid}',headers=headerx).content
        base64_img = base64.b64encode(dat).decode('utf-8')
        print('data:image/png;base64,' + base64_img)
        if not dat:
            print('验证码请求失败')
            return None
        code = self.ocr(base64_img)
        if not code:
            return None
        code = replace_code(code)
        if not (len(code) == 4 and code.isdigit()):
            print('识别验证码出错')
            return None
        return {'uuid': random_uuid, 'code': code}

def replace_code(text):
    replacements = {
        'y': '9',
        '口': '0',
        'q': '0',
        'u': '0',
        'o': '0',
        '>': '1',
        'd': '0',
        'b': '8',
    }
    text = text.replace('566', '5066')
    return ''.join(replacements.get(c, c) for c in text)

if __name__ == "__main__":
    sp = Spider()
    formatJo = sp.init(
        '''{
            "host": "https://cdn-tupic-duofun-neimenggu.56uxi.com/2.txt",
            "api": "/api.php/qijiappapi",
            "datakey": "qwertyuiopqwertt",
            "dataiv": "qwertyuiopqwertt"
        }'''
    ) # 初始化
    # formatJo = sp.homeContent(False) # 筛选分类(首页 可选)
    # formatJo = sp.homeVideoContent() # (首页 可选)
    formatJo = sp.searchContent("加油吧实习生",False,'1') # 搜索
    # formatJo = sp.categoryContent('', '1', False, {}) # 分类
    # formatJo = sp.detailContent(['65931']) # 详情
    # formatJo = sp.playerContent("","http://47.105.35.52:909/api/?key=BvaxhepLyijZrC24N8&url=,XL-5205bbaa42abb4ced7b2fa27222c2b210,token+,2",{}) # 播放
    # formatJo = sp.localProxy({"":""}) # 代理
    print(formatJo)

'''{
    "host": "https://cdn-tupic-duofun-neimenggu.56uxi.com/2.txt",
    "api": "/api.php/qijiappapi.index",
    "datakey": "qwertyuiopqwertt",
    "dataiv": "qwertyuiopqwertt"
}'''

'''{
    "host": "https://appcms.tzys.xyz",
    "api": "/api.php/getappapi.index",
    "datakey": "KL6vlZkw6WL5x90U",
    "dataiv": "KL6vlZkw6WL5x90U"
}'''